package se.perp.c4.ui;

import se.perp.c4.control.iface.IPieceSelectionListener;
import java.awt.Point;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import se.perp.c4.model.Actor;
import se.perp.c4.model.Actor.EActor;
import se.perp.c4.control.iface.IGamePieceListener;
import se.perp.c4.model.Actor.Side;
import static se.perp.c4.model.Actor.EActor.*;

public class PieceCollection implements Iterable<GamePiece> {

    private Map<EActor, GamePiece> pieces = new HashMap<EActor, GamePiece>();

    public PieceCollection() {
        pieces.put(FRODO, new LightPiece(FRODO, "Frodo"));
        pieces.put(SAM, new LightPiece(SAM, "Sam"));
        pieces.put(MERRY, new LightPiece(MERRY, "Merry"));
        pieces.put(PIPPIN, new LightPiece(PIPPIN, "Pippin"));
        pieces.put(GIMLI, new LightPiece(GIMLI, "Gimli"));
        pieces.put(LEGOLAS, new LightPiece(LEGOLAS, "Legolas"));
        pieces.put(ARAGORN, new LightPiece(ARAGORN, "Aragorn"));
        pieces.put(BOROMIR, new LightPiece(BOROMIR, "Boromir"));
        pieces.put(GANDALF, new LightPiece(GANDALF, "Gandalf"));

        pieces.put(SHELOB, new DarkPiece(SHELOB, "Shelob"));
        pieces.put(WARG, new DarkPiece(WARG, "Warg"));
        pieces.put(WITCHKING, new DarkPiece(WITCHKING, "W.King"));
        pieces.put(BALROG, new DarkPiece(BALROG, "Balrog"));
        pieces.put(ORCS, new DarkPiece(ORCS, "Orcs"));
        pieces.put(SARUMAN, new DarkPiece(SARUMAN, "Saruman"));
        pieces.put(B_RIDERS, new DarkPiece(B_RIDERS, "B.Riders"));
        pieces.put(F_NAZGUL, new DarkPiece(F_NAZGUL, "F.Nazg."));
        pieces.put(CAVETROLL, new DarkPiece(CAVETROLL, "C.Troll"));
    }

    public void setGamePieceListener(IGamePieceListener l) {
        for (GamePiece p : this) {
            p.setGamePieceListener(l);
        }
    }

    public GamePiece get(EActor actorId) {
        return pieces.get(actorId);
    }

    public GamePiece getAtThatsNot(Point p, GamePiece pc) {
        return getAtThatsNot(p.x, p.y, pc);
    }

    public GamePiece getAtThatsNot(int x, int y, GamePiece pc) {
        for (GamePiece gp : pieces.values()) {
            if (gp.getBounds().contains(x, y) && gp != pc && gp.isVisible()) {
                return gp;
            }
        }
        return null;
    }


    public void setSideKnown(Actor.Side side, boolean known) {
        for (GamePiece gp : pieces.values()) {
            if (Actor.sideFor(gp.getActor()) == side) {
                gp.setKnown(known);
            }
        }
    }

    public void setSideMovable(Actor.Side side, boolean responsive) {
        for (GamePiece gp : pieces.values()) {
            if (Actor.sideFor(gp.getActor()) == side) {
                gp.setMovable(responsive);
            }
        }
    }

    public Iterator<GamePiece> iterator() {
        return pieces.values().iterator();
    }

    public void enterPieceSelectionMode(Collection<EActor> selectableActors) {
        for (GamePiece gp : pieces.values()) {
            gp.setSelectionMode(true);
            if (selectableActors.contains(gp.getActor())) {
                gp.setSelectable(true);
                gp.repaint();
            }
        }
    }

    public void exitPieceSelectionMode() {
        for (GamePiece gp : pieces.values()) {
            gp.setSelectionMode(false);
            gp.repaint();
        }
    }

    public void setPieceSelectionListener(IPieceSelectionListener pieceSelectionListener) {
        for (GamePiece gp : pieces.values()) {
            gp.setPieceSelectionListener(pieceSelectionListener);
        }
    }

    public void setAllVisible(boolean visible) {
        for (GamePiece gp : pieces.values()) {
            gp.setVisible(visible);
        }
    }

    public void setSideVisible(Side side, boolean visible) {
        for (GamePiece gp : pieces.values()) {
            if (Actor.sideFor(gp.getActor()) == side) {
                gp.setVisible(visible);
            }
        }
    }


   @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (GamePiece gp: pieces.values()) {
            sb.append(gp.toString()+"\n");
        }
        return sb.toString();
    }

    public void unmarkAll() {
        for (GamePiece gp : pieces.values()) {
            gp.unmark();
        }
    }

    public void setAllNormalBackground() {
        for (GamePiece gp : pieces.values()) {
            gp.setNormalBackground();
        }
    }

}
